import numpy as np  
  
def update_defect_rate(total, defective, sample_size):  
    """  
    更新次品率，根据抽样的结果。  
    total: 总数  
    defective: 次品数  
    sample_size: 抽样样本数  
    """  
    # 抽样数据  
    sample_defective = np.random.binomial(sample_size, defective / total)  # 根据次品率生成样本中次品数  
    # 更新后的次品率  
    updated_defect_rate = sample_defective / sample_size  
    return updated_defect_rate

import os  
import numpy as np  
import matplotlib.pyplot as plt  
from deap import base, creator, tools, algorithms  
  

# 定义成本计算函数  
def calculate_total_cost(decision_vars, parameters):  
    x1, x2, xf, xd = decision_vars  
    p1, p2, C_assemble, C_finished, C_dismantle, C_exchange, Ct1, Ct2, n1, n2, n_finished = parameters  
      
    # 零配件检测成本  
    cost_parts = x1 * Ct1 * n1 + x2 * Ct2 * n2  
      
    # 装配成本  
    cost_assemble = C_assemble * n_finished  
      
    # 产品检测成本  
    cost_product = xf * C_finished * n_finished  
      
    # 成品次品率计算  
    p_assembly = (1 - x1) * p1 + (1 - x2) * p2 - (1 - x1) * (1 - x2) * p1 * p2  
    pf = 1 - (1 - p_assembly) ** 2  
      
    # 拆解和调换成本  
    cost_rework = xd * C_dismantle * pf * n_finished  
    cost_replace = (1 - xd) * C_exchange * pf * n_finished  
      
    # 总成本  
    total_cost = cost_parts + cost_assemble + cost_product + cost_rework + cost_replace  
      
    return total_cost  
  

# 创建遗传算法个体和种群  
def create_individual_and_population(toolbox, n_variables):  
    toolbox.register("attr_bool", np.random.randint, 2)  
    toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_bool, n_variables)  
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)  
  

# 注册遗传算法操作  
def register_ga_operations(toolbox):  
    toolbox.register("mate", tools.cxTwoPoint)  
    toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)  
    toolbox.register("select", tools.selTournament, tournsize=3)  
  

# 执行遗传算法  
def run_genetic_algorithm(toolbox, population, n_gen, stats, verbose=False):  
    result, log = algorithms.eaSimple(population, toolbox, cxpb=0.7, mutpb=0.2, ngen=n_gen,  
                                     stats=stats, halloffame=None, verbose=verbose)  
    return result, log  
  

# 在全局范围内创建类
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))  
creator.create("Individual", list, fitness=creator.FitnessMin) 

# 初始化并运行优化  
def optimize_cost(parameters, count):   
      
    toolbox = base.Toolbox()  
      
    # 创建个体和种群  
    n_variables = 4  # x1, x2, xf, xd  
    create_individual_and_population(toolbox, n_variables)  
      
    # 定义适应度函数  
    def eval_cost(individual):  
        return calculate_total_cost(individual, parameters),  
      
    toolbox.register("evaluate", eval_cost)  
      
    # 注册遗传算法操作  
    register_ga_operations(toolbox)  
      
    # 设置种群大小和代数  
    population = toolbox.population(n=60)  
    n_gen = 50  
      
    # 初始化统计信息对象  
    stats = tools.Statistics(lambda ind: ind.fitness.values)  
    stats.register("avg", np.mean)  
    stats.register("std", np.std)  
    stats.register("min", np.min)  
    stats.register("max", np.max)  
      
    # 运行遗传算法  
    result, log = run_genetic_algorithm(toolbox, population, n_gen, stats)  
      
    # 找到最优解  
    best_individual = tools.selBest(population, k=1)[0]  
    print(f"Best Individual: {best_individual} (x1, x2, xf, xd)")  
    print(f"Minimum Cost: {eval_cost(best_individual)[0]}")  
      
    # 绘制迭代图  
    generations = log.select("gen")  
    avg_costs = log.select("avg")  
      
    plt.figure(figsize=(10, 6))  
    plt.plot(generations, avg_costs, marker='o', linestyle='-', color='b')  
    plt.title('Average Cost per Generation')  
    plt.xlabel('Generation')  
    plt.ylabel('Average Cost')  
    plt.grid(True)  
      
    # 确保输出文件夹存在  
    output_dir = 'test4_2_genetic_picture'  
    if not os.path.exists(output_dir):  
        os.makedirs(output_dir)  
      
    # 保存图片到指定文件夹  
    plt.savefig(os.path.join(output_dir, f'average_cost_per_generation{count}.png'))  
    plt.close()  


# 更新零配件1次品率
parts_total_1 = [1000] * 6
parts_defective_1 = [100 , 200, 100 , 200, 100, 50]
updated_parts_defect_rates_1 = [update_defect_rate(parts_total_1[i], parts_defective_1[i], 100) for i in range(6)]

# 更新零配件2次品率
parts_total_2 = [1000] * 6
parts_defective_2 = [100 , 200, 100 , 200, 200, 50]
updated_parts_defect_rates_2 = [update_defect_rate(parts_total_2[i], parts_defective_2[i], 100) for i in range(6)]

# 更新成品次品率  
product_total = [1000] * 6 # 成品的总数  
product_defective = [100, 200, 100, 200, 100, 50]  # 成品的次品数  
updated_product_defect_rate = [update_defect_rate(product_total[i], product_defective[i], 70)for i in range(6)]

print("零配件1次品率：", updated_parts_defect_rates_1)
print("零配件2次品率：", updated_parts_defect_rates_2)
print("成品次品率：", updated_product_defect_rate)

# 参数设置  
parameters_list = [  
    (updated_parts_defect_rates_1[0], updated_parts_defect_rates_2[0], 6, 3, 5, 6, 2, 3, 100, 100, 70),  
    (updated_parts_defect_rates_1[1], updated_parts_defect_rates_1[1], 6, 3, 5, 6, 2, 3, 100, 100, 70),  
    (updated_parts_defect_rates_1[2], updated_parts_defect_rates_1[2], 6, 3, 5, 30, 2, 3, 100, 100, 70),  
    (updated_parts_defect_rates_1[3], updated_parts_defect_rates_1[3], 6, 2, 5, 30, 1, 1, 100, 100, 70),  
    (updated_parts_defect_rates_1[4], updated_parts_defect_rates_1[4], 6, 2, 5, 10, 8, 1, 100, 100, 70),  
    (updated_parts_defect_rates_1[5], updated_parts_defect_rates_1[5], 6, 3, 40, 10, 2, 3, 100, 100, 70)  
]  
  
# 调用优化函数  
for index, parameters in enumerate(parameters_list, start=1):  
    optimize_cost(parameters, index)